﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Waves : MonoBehaviour {

	public class DataClass
	{
		public float a;
		public int lastSingleCount;
		public float angle;
		public int baseIndex;
		public float oY;
		public int remian;
		public bool isHalf;
	}

	[HideInInspector]
	public List<DataClass> dataList;
	private MeshFilter filter;
	private Mesh mesh;
	private PolygonCollider2D pcollider2D;
	[HideInInspector]
	public int vertCount;

	[HideInInspector]
	public Vector3[] nowVertex;  
	private List<int> indexs;
	[HideInInspector]
	public float WaveLength;
	[HideInInspector]
	public float m_lastY = 0f;
	[HideInInspector]
	public int m_remain;
	[HideInInspector]
	public float m_lastA;
	[HideInInspector]
	public float m_lastB;
	[HideInInspector]
	public int m_lastSingleCount;
	[HideInInspector]
	public float m_lastAngle;
	[HideInInspector]
	public float m_xOff=0.01f;
	[HideInInspector]
	public float WaveHalfHeight = 0.5f;
	public int type = 1;
	[HideInInspector]
	public float height;
	public void Init (float scale) {
		vertCount = 360*5;
		filter = GetComponent<MeshFilter> ();
		pcollider2D = GetComponent<PolygonCollider2D> ();
		filter.mesh = mesh = new Mesh ();
		nowVertex = new Vector3[vertCount*2];
		indexs = new List<int> ();
		WaveLength = (vertCount-1) * m_xOff;
		dataList = new List<DataClass> ();
		for (var i = 0; i < vertCount; i++) {
			nowVertex [i] = new Vector3 (i*m_xOff, 0, 0f);
		}
		if (type == 1) {
			height = -3.5f*2;
		} else {
			height = -4f*2;
		}
		for (var i = vertCount; i < vertCount * 2; i++) {
			if (type == 1) {
				nowVertex [i] = new Vector3 ((i-vertCount)*m_xOff, height/2, 0f);
			} else {
				nowVertex [i] = new Vector3 ((i-vertCount)*m_xOff, height/2, 0f);
			}
		}
		for (var i = 0; i < vertCount-2; i++) {
			int v0 = i;
			int v1 = i + 1;
			int v2 = i + vertCount;
			int v3 = i + 1 + vertCount;
			indexs.Add (v0);
			indexs.Add (v2);
			indexs.Add (v3);
			indexs.Add (v0);
			indexs.Add (v1);
			indexs.Add (v3);
		}
		GetComponent<WaveRender> ().Init ();
		transform.localScale = new Vector3 (scale, scale, scale);
	}

	public void dealRemain(float la, float lb, int remian, float ang, int lastSingleCount, ref int index, ref float baseY){
		float oY = 0;
		for (var i = 0; i < remian; i++) {
			var nowX = lastSingleCount - remian + i;
			nowVertex [i + index].y = la * Mathf.Sin (Mathf.Deg2Rad * (nowX / (float)(lastSingleCount-1) * 180 + ang));
			if (i == 0) {
				float newY = nowVertex [i + index].y;
				oY = newY - baseY;
			}
			nowVertex [i + index].y -= oY;
		}
		DataClass dataC = new DataClass ();
		dataC.a = la;
		dataC.lastSingleCount = lastSingleCount;
		dataC.angle = ang;
		dataC.baseIndex = index;
		dataC.oY = oY;
		dataC.remian = remian;
		dataC.isHalf = true;
		dataList.Add (dataC);
		index += remian;
		baseY = nowVertex[index-1].y;
	}

	public void Generate2(){
		var count = 2;
		float single = vertCount / count;
		int index = 0;
		for (var i = 0; i < 2; i++) {
			for (var k = 0; k < (int)single; k++) {
				nowVertex [k + index].y = Mathf.Sin (Mathf.Deg2Rad * (k / single * Mathf.PI * 2));
			}
			index += (int)single;
		}
		mesh.vertices = nowVertex;
		mesh.triangles = indexs.ToArray ();
	}

	//180度一个
	public void Generate(float baseY, int index, float ang){
		var count = 2;
		float single = vertCount / count;
		single /= 2f;
		float maxA = 0.8f;
		float minA = 0.3f;
		float minB = 0.7f;
		float maxB = 1.0f;
		bool has = false;
		while (index < vertCount) {
			int k = 0;
			if (ang == 90f) {
				k = 1;
				ang = 270f;
			}
			for (; k < 2; k++) {
				float angle = 0;
				switch (k) {
				case 0:
					angle = 90;
					break;
				case 1:
					angle = 270;
					break;
				}
				float oldY = 0;
				if (index > 0) {
					oldY = nowVertex [index - 1].y;
				} else {
					oldY = baseY;
				}
				float oY = 0;
				float a = Random.Range(minA, maxA);
				float b = Random.Range (minB, maxB);
				m_lastA = a;
				m_lastB = b;
				int x = Mathf.RoundToInt (b * single);
				int end = x;
				if((index + x) >= vertCount){
					end = vertCount - index;
					m_remain = x - end;
					has = true;
				}
				m_lastSingleCount = x;
				m_lastAngle = angle;
				for (var i = 0; i < end; i++) {
					nowVertex [i + index].y = a * Mathf.Sin (Mathf.Deg2Rad * (i/(float)(x-1)*180 + angle));
					if (i == 0) {
						float newY = nowVertex [i + index].y;
						oY = newY - oldY;
					}
					nowVertex [i + index].y -= oY;
				}
				if (has == false) {
					if (nowVertex [index + end - 1].y >= WaveHalfHeight) {
						k = -1;
					} else if (nowVertex [index + end - 1].y <= -WaveHalfHeight) {
						k = 0;
					}
				}
				DataClass dataC = new DataClass ();
				dataC.a = a;
				dataC.lastSingleCount = x;
				dataC.angle = angle;
				dataC.baseIndex = index;
				dataC.oY = oY;
				dataC.remian = end;
				dataC.isHalf = false;
				dataList.Add (dataC);
				index += end;
				if (has)
					break;
			}
			if (has)
				break;
		}
		if (!has) {
			m_remain = 0;
		}
		m_lastY = nowVertex [vertCount - 1].y;
		mesh.vertices = nowVertex;
		mesh.triangles = indexs.ToArray ();
	}

	public void Reset(float baseY, bool hasArgs, float la, float lb, int remain, float ang, int lastSingleCount){
		int index = 0;
		m_remain = 0;
		m_lastSingleCount = 0;
		m_lastA = 0f;
		m_lastB = 0f;
		m_lastAngle = 0f;
		m_lastY = 0f;
		dataList.Clear ();
		if (hasArgs) {
			dealRemain (la, lb, remain, ang, lastSingleCount, ref index, ref baseY);
		} 
		Generate (baseY, index, ang);
		if (pcollider2D != null) {
			GenerateCollider ();
		}
		GetComponent<WaveRender> ().GenerateRender ();
	}

	public void GenerateCollider(){
		int count = vertCount / 10 / 10 + 1;
		Vector2[] points = new Vector2[count*2];
		for (var i = 0; i < count; i++) {
			int index = i * 10*10;
			if (index > 0) {
				index -= 1;
			}
			points [i] = new Vector2 (nowVertex[index].x, nowVertex[index].y-1f);
		}
		for (var i = 0; i < count; i++) {
			int index = 0;
			int newI = 0;
			if (i == 0) {
				index = i * 10 * 10;
				newI = vertCount - index - 1;
			} else if (i < count - 1) {
				index = i * 10 * 10 + 1;
				newI = vertCount - index;
			} else {
				index = i * 10 * 10;
				newI = vertCount - index;
			}
			points [i + count] = new Vector2 (nowVertex [vertCount + newI].x, nowVertex [vertCount + newI].y);
		}
		pcollider2D.points = points;
	}

	void OnTriggerEnter2D(Collider2D collider){
		if (collider.gameObject.name == "BodyCol") {
			Debug.Log("Wave Col to BodyCol");
			StartCoroutine (showGameOver());
		}
	}

	IEnumerator showGameOver(){ 
		yield return new WaitForSeconds(1);
		CanvaController conl = GameObject.Find ("Canvas").GetComponent<CanvaController>();
		conl.ShowGameOver ();
		Debug.Log ("Fill water");
	}

}
